home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / DirectPlay / Tutorials / Tut09_ClientServer / Server / Server.cpp next >
C/C++ Source or Header  |  2001-10-08  |  12KB  |  363 lines

  1. //----------------------------------------------------------------------------
  2. // File: server.cpp
  3. //
  4. // Desc: This simple program builds upon the 5th tutorial, and is the server
  5. //       code for the server in the client/server model
  6. //
  7. // Copyright (c) 2000-2001 Microsoft Corp. All rights reserved.
  8. //-----------------------------------------------------------------------------
  9. #define INITGUID
  10. #define _WIN32_DCOM
  11. #include <stdio.h>
  12. #include <dplay8.h>
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Global variables
  16. //-----------------------------------------------------------------------------
  17. IDirectPlay8Server*                 g_pDPServer      = NULL;
  18. IDirectPlay8Address*                g_pDeviceAddress = NULL;
  19. IDirectPlay8Address*                g_pHostAddress   = NULL;
  20.  
  21. // This GUID allows DirectPlay to find other instances of the same game on
  22. // the network.  So it must be unique for every game, and the same for 
  23. // every instance of that game.  // {1AD4CA3B-AC68-4d9b-9522-BE59CD485276}
  24. GUID g_guidApp = { 0x1ad4ca3b, 0xac68, 0x4d9b, { 0x95, 0x22, 0xbe, 0x59, 0xcd, 0x48, 0x52, 0x76 } };
  25.  
  26.  
  27. //-----------------------------------------------------------------------------
  28. // Function-prototypes
  29. //-----------------------------------------------------------------------------
  30. HRESULT WINAPI DirectPlayMessageHandler(PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer);
  31. BOOL    IsServiceProviderValid(const GUID* pGuidSP);
  32. HRESULT InitDirectPlay();
  33. HRESULT CreateDeviceAddress();
  34. HRESULT HostSession();
  35. HRESULT SendDirectPlayMessage();
  36. void    CleanupDirectPlay();
  37.  
  38.  
  39. //-----------------------------------------------------------------------------
  40. // Miscellaneous helper functions
  41. //-----------------------------------------------------------------------------
  42. #define SAFE_DELETE(p)          {if(p) {delete (p);     (p)=NULL;}}
  43. #define SAFE_DELETE_ARRAY(p)    {if(p) {delete[] (p);   (p)=NULL;}}
  44. #define SAFE_RELEASE(p)         {if(p) {(p)->Release(); (p)=NULL;}}
  45.  
  46. #define USER_EXIT       1
  47. #define USER_SEND       2
  48.  
  49.  
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Name: main()
  54. // Desc: Entry point for the application.  
  55. //-----------------------------------------------------------------------------
  56. int main(int argc, char* argv[], char* envp[])
  57. {
  58.     HRESULT                     hr;
  59.     int                         iUserChoice;
  60.  
  61.     // Init COM so we can use CoCreateInstance
  62.     CoInitializeEx(NULL, COINIT_MULTITHREADED);
  63.  
  64.     // Init the DirectPlay system
  65.     if( FAILED( hr = InitDirectPlay() ) )
  66.     {
  67.         printf("Failed Initializing DirectPlay:  0x%X\n", hr);
  68.         goto LCleanup;
  69.     }
  70.  
  71.     if( FAILED( hr = CreateDeviceAddress() ) )
  72.     {
  73.         printf("Failed CreatingDeviceAddress:  0x%X\n", hr);
  74.         goto LCleanup;
  75.     }
  76.  
  77.     if( FAILED( hr = HostSession() ) )
  78.     {
  79.         printf("Failed Hosting:  0x%X\n", hr);
  80.         goto LCleanup;
  81.     }
  82.  
  83.     // Present User with Choices
  84.     do
  85.     {
  86.         printf("Please select one.\n1.  Exit\n2.  Send Data\n");
  87.         scanf("%d", &iUserChoice);
  88.  
  89.         if( iUserChoice == USER_SEND )
  90.         {
  91.             if( FAILED( hr = SendDirectPlayMessage() ) )
  92.             {
  93.                 printf("Failed To Send Data:  0x%X\n", hr);
  94.                 goto LCleanup;
  95.             }
  96.         }
  97.     } while (iUserChoice != USER_EXIT);
  98.  
  99.     
  100. LCleanup:
  101.     CleanupDirectPlay();
  102.  
  103.     // ShutDown COM
  104.     CoUninitialize();
  105.  
  106.     return 0;
  107. }
  108.  
  109.  
  110.  
  111.  
  112. //-----------------------------------------------------------------------------
  113. // Name: InitDirectPlay()
  114. // Desc: Initialize DirectPlay
  115. //-----------------------------------------------------------------------------
  116. HRESULT InitDirectPlay()
  117. {
  118.     HRESULT     hr = S_OK;
  119.  
  120.     // Create the IDirectPlay8Server Object
  121.     if( FAILED( hr = CoCreateInstance(CLSID_DirectPlay8Server, NULL, 
  122.                                     CLSCTX_INPROC_SERVER,
  123.                                     IID_IDirectPlay8Server, 
  124.                                     (LPVOID*) &g_pDPServer ) ) )
  125.     {
  126.         printf("Failed Creating the IDirectPlay8Peer Object:  0x%X\n", hr);
  127.         goto LCleanup;
  128.     }
  129.  
  130.     // Init DirectPlay
  131.     if( FAILED( hr = g_pDPServer->Initialize(NULL, DirectPlayMessageHandler, 0 ) ) )
  132.     {
  133.         printf("Failed Initializing DirectPlay:  0x%X\n", hr);
  134.         goto LCleanup;
  135.     }
  136.     
  137.     // Ensure that TCP/IP is a valid Service Provider
  138.     if( FALSE == IsServiceProviderValid(&CLSID_DP8SP_TCPIP ) )
  139.     {
  140.         hr = E_FAIL;
  141.         printf("Failed validating CLSID_DP8SP_TCPIP");
  142.         goto LCleanup;
  143.     }
  144.  
  145. LCleanup:
  146.     return hr;
  147. }
  148.  
  149.  
  150.  
  151.  
  152. //-----------------------------------------------------------------------------
  153. // Name: IsServiceProviderValid()
  154. // Desc: Return TRUE if the service provider is valid
  155. //-----------------------------------------------------------------------------
  156. BOOL IsServiceProviderValid(const GUID* pGuidSP)
  157. {
  158.     HRESULT                     hr;
  159.     DPN_SERVICE_PROVIDER_INFO*  pdnSPInfo = NULL;
  160.     DWORD                       dwItems = 0;
  161.     DWORD                       dwSize = 0;
  162.  
  163.     hr = g_pDPServer->EnumServiceProviders(&CLSID_DP8SP_TCPIP, NULL, NULL, &dwSize, &dwItems, 0);
  164.  
  165.     if( hr != DPNERR_BUFFERTOOSMALL)
  166.     {
  167.         printf("Failed Enumerating Service Providers:  0x%x\n", hr);
  168.         goto LCleanup;
  169.     }
  170.  
  171.     pdnSPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  172.  
  173.     if( FAILED( hr = g_pDPServer->EnumServiceProviders(&CLSID_DP8SP_TCPIP, NULL, pdnSPInfo, &dwSize, &dwItems, 0 ) ) )
  174.     {
  175.         printf("Failed Enumerating Service Providers:  0x%x\n", hr);
  176.         goto LCleanup;
  177.     }
  178.  
  179.     // There are no items returned so the requested SP is not available
  180.     if( dwItems == 0)
  181.     {
  182.         hr = E_FAIL;
  183.     }
  184.  
  185. LCleanup:
  186.     SAFE_DELETE_ARRAY(pdnSPInfo);
  187.     if( SUCCEEDED(hr) )
  188.         return TRUE;
  189.     else
  190.         return FALSE;
  191. }
  192.  
  193.  
  194.  
  195.  
  196. //-----------------------------------------------------------------------------
  197. // Name: DirectPlayMessageHandler
  198. // Desc: Handler for DirectPlay messages.  
  199. //-----------------------------------------------------------------------------
  200. HRESULT WINAPI DirectPlayMessageHandler(PVOID pvUserContext, DWORD dwMessageId, PVOID pMsgBuffer)
  201. {
  202.     HRESULT     hr = S_OK;
  203.  
  204.     switch (dwMessageId)
  205.     {
  206.     case DPN_MSGID_RECEIVE:
  207.         {
  208.             PDPNMSG_RECEIVE     pMsg;
  209.  
  210.             pMsg = (PDPNMSG_RECEIVE) pMsgBuffer;
  211.  
  212.             printf("\nReceived Message:  %S\n", (WCHAR*)pMsg->pReceiveData);
  213.             break;
  214.         }
  215.     }
  216.     return hr;
  217. }
  218.  
  219.  
  220.  
  221.  
  222. //-----------------------------------------------------------------------------
  223. // Name: CreateDeviceAddress()
  224. // Desc: Creates a device address
  225. //-----------------------------------------------------------------------------
  226. HRESULT CreateDeviceAddress()
  227. {
  228.     HRESULT         hr = S_OK;
  229.  
  230.     // Create our IDirectPlay8Address Device Address
  231.     if( FAILED( hr = CoCreateInstance(CLSID_DirectPlay8Address, NULL,
  232.                                     CLSCTX_INPROC_SERVER,
  233.                                     IID_IDirectPlay8Address,
  234.                                     (LPVOID*) &g_pDeviceAddress ) ) )
  235.     {
  236.         printf("Failed Creating the IDirectPlay8Address Object:  0x%X\n", hr);
  237.         goto LCleanup;
  238.     }
  239.     
  240.     // Set the SP for our Device Address
  241.     if( FAILED( hr = g_pDeviceAddress->SetSP(&CLSID_DP8SP_TCPIP ) ) )
  242.     {
  243.         printf("Failed Setting the Service Provider:  0x%X\n", hr);
  244.         goto LCleanup;
  245.     }
  246.  
  247. LCleanup:
  248.     return hr;
  249. }
  250.  
  251.  
  252.  
  253.  
  254. //-----------------------------------------------------------------------------
  255. // Name: HostSession()
  256. // Desc: Host a DirectPlay session
  257. //-----------------------------------------------------------------------------
  258. HRESULT HostSession()
  259. {
  260.     HRESULT                 hr = S_OK;
  261.     DPN_APPLICATION_DESC    dpAppDesc;
  262.     DPN_PLAYER_INFO         dpPlayerInfo;
  263.     WCHAR                   wszSession[128];
  264.     WCHAR                   wszName[] = L"Server";
  265.  
  266.  
  267.     ZeroMemory(&dpPlayerInfo, sizeof(DPN_PLAYER_INFO));
  268.     dpPlayerInfo.dwSize = sizeof(DPN_PLAYER_INFO);
  269.     dpPlayerInfo.dwInfoFlags = DPNINFO_NAME;
  270.     dpPlayerInfo.pwszName = wszName;
  271.     dpPlayerInfo.pvData = NULL;
  272.     dpPlayerInfo.dwDataSize = NULL;
  273.     dpPlayerInfo.dwPlayerFlags = 0;
  274.  
  275.     if( FAILED( hr = g_pDPServer->SetServerInfo( &dpPlayerInfo, NULL, NULL, 
  276.                                                  DPNSETSERVERINFO_SYNC ) ) )
  277.     {
  278.         printf("Failed Hosting:  0x%X\n", hr);
  279.         goto LCleanup;
  280.     }
  281.  
  282.     // Prompt the user for the session name
  283.     printf("\nPlease Enter a Session Name.\n");
  284.     wscanf(L"%ls", wszSession);
  285.  
  286.     // Now set up the Application Description
  287.     ZeroMemory(&dpAppDesc, sizeof(DPN_APPLICATION_DESC));
  288.     dpAppDesc.dwSize = sizeof(DPN_APPLICATION_DESC);
  289.     dpAppDesc.dwFlags = DPNSESSION_CLIENT_SERVER;
  290.     dpAppDesc.guidApplication = g_guidApp;
  291.     dpAppDesc.pwszSessionName = wszSession;
  292.  
  293.     // We are now ready to host the app
  294.     if( FAILED( hr = g_pDPServer->Host(&dpAppDesc,       // AppDesc
  295.                                 &g_pDeviceAddress, 1,    // Device Address
  296.                                 NULL, NULL,              // Reserved
  297.                                 NULL,                    // Player Context
  298.                                 0 ) ) )                  // dwFlags
  299.     {
  300.         printf("Failed Hosting:  0x%X\n", hr);
  301.         goto LCleanup;
  302.     }
  303.     else
  304.     {
  305.         printf("Currently Hosting...\n");
  306.     }
  307.  
  308. LCleanup:
  309.     return hr;
  310. }
  311.  
  312.  
  313.  
  314.  
  315. //-----------------------------------------------------------------------------
  316. // Name: SendDirectPlayMessage()
  317. // Desc: Sends a DirectPlay message to all players
  318. //-----------------------------------------------------------------------------
  319. HRESULT SendDirectPlayMessage()
  320. {
  321.     HRESULT         hr = S_OK;
  322.     DPN_BUFFER_DESC dpnBuffer;
  323.     WCHAR           wszData[256];
  324.  
  325.     // Get the data from the user
  326.     printf("\nPlease Enter a String.\n");
  327.     wscanf(L"%ls", wszData);
  328.  
  329.     dpnBuffer.pBufferData = (BYTE*) wszData;
  330.     dpnBuffer.dwBufferSize = 2 * (wcslen(wszData) + 1);
  331.  
  332.     if( FAILED( hr = g_pDPServer->SendTo(DPNID_ALL_PLAYERS_GROUP,   // dpnid
  333.                                     &dpnBuffer,                     // pBufferDesc
  334.                                     1,                              // cBufferDesc
  335.                                     0,                              // dwTimeOut
  336.                                     NULL,                           // pvAsyncContext
  337.                                     NULL,                           // pvAsyncHandle
  338.                                     DPNSEND_SYNC |                  // dwFlags
  339.                                     DPNSEND_NOLOOPBACK ) ) )        
  340.     {
  341.         printf("Failed Sending Data:  0x%x\n", hr);
  342.     }
  343.     return hr;
  344. }
  345.  
  346.  
  347.  
  348.  
  349. //-----------------------------------------------------------------------------
  350. // Name: CleanupDirectPlay()
  351. // Desc: Cleanup DirectPlay
  352. //-----------------------------------------------------------------------------
  353. void CleanupDirectPlay()
  354. {
  355.     // Shutdown DirectPlay
  356.     if( g_pDPServer)
  357.         g_pDPServer->Close(0);
  358.  
  359.     SAFE_RELEASE(g_pDeviceAddress);
  360.     SAFE_RELEASE(g_pHostAddress);
  361.     SAFE_RELEASE(g_pDPServer);
  362. }
  363.